package com.caigou.service.impl;

import com.caigou.bean.cms.entity.Article;
import com.caigou.bean.cms.entity.Comment;
import com.caigou.bean.cms.param.CommentFilterParam;
import com.caigou.bean.cms.param.CommentParam;
import com.caigou.bean.cms.param.CommentQueryParam;
import com.caigou.bean.exam.entity.UserInfo;
import com.caigou.bean.exam.entity.Users;
import com.caigou.component.RedisObjectComponent;
import com.caigou.constant.NewsConstant;
import com.caigou.enums.Constant;
import com.caigou.enums.FailResultEnum;
import com.caigou.enums.ResponseEnum;
import com.caigou.exception.NotFoundCommentException;
import com.caigou.mapper.cms.ArticleMapper;
import com.caigou.mapper.cms.BanWordsMapper;
import com.caigou.mapper.cms.CommentMapper;
import com.caigou.mapper.exam.UserInfoMapper;
import com.caigou.mapper.exam.UsersMapper;
import com.caigou.service.IBanWordsService;
import com.caigou.service.ICommentService;
import com.caigou.util.Result;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Slf4j
@Service
public class CommentServiceImpl implements ICommentService {

    @Resource
    private CommentMapper commentMapper;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private IBanWordsService banWordsService;

    @Resource
    private RedisObjectComponent redisObjectComponent;


    @Override
    public Result<List<Comment>> findCommentByCommentTargetId(CommentParam param) {
        List<Comment> list = commentMapper.findCommentByCommentTargetId(param.getCommentTargetId());
        return Result.success(list);
    }

    @Override
    public synchronized Result<Integer> addCommentByComment(CommentParam param, Users user) {
        Comment comment = new Comment();
        BeanUtils.copyProperties(param, comment);
        String commentId = UUID.randomUUID().toString().trim().replaceAll("-", "");

//        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
//        Calendar calendar = Calendar.getInstance();
//        String dateName = df.format(calendar.getTime());
        //String commentId = String.format(NewsConstant.COMMENT_PREFIX, "");
        if (StringUtils.isEmpty(param.getCommentTargetId())) {
            return Result.error(ResponseEnum.NO_COMMENT_ID);
        }
        comment.setCommentId(commentId);
        comment.setIsDelete(0);
        comment.setCreateTime(new Date());
        comment.setUpdateTime(new Date());
        comment.setUserid(user.getUserid());
        comment.setCommentType(param.getCommentType());
        comment.setTel(user.getTel());
        UserInfo userInfo = userInfoMapper.findUserInfoByUserId(user.getUserid());
        if (userInfo != null) {
            comment.setNickname(userInfo.getNickname());
        }
        if (param.getCommentType() == 2) {
            if (!StringUtils.isEmpty(param.getReplyCommentId())) {
                Comment comment1 = commentMapper.findCommentByCommentId(param.getReplyCommentId());
                if (comment1 == null) {
                    return Result.error(ResponseEnum.NOT_FOUND_COMMENT);
                }
            }
        }
        int insertNum = commentMapper.insertSelective(comment);
        return Result.success(insertNum);
    }

    @Override
    public synchronized Result addComment(CommentParam param, Users user) {
        String articleId = param.getCommentTargetId();
        Article article = articleMapper.getArticle(articleId);
        if (article == null) {
            return Result.error(FailResultEnum.NO_FIND_ARTICLE);
        }
        String comments = param.getComments();
        if (StringUtils.isEmpty(comments) || comments.length()>300 || StringUtils.isEmpty(comments.trim())) {
            return Result.error(FailResultEnum.COMMENTS_PARAM_ERROR);
        }

        if (article.getArticleCommentStatus() == 0) {
            log.info("文章articleId={}禁止评论，articleCommentStatus={}", articleId, article.getArticleCommentStatus());
            return Result.error("此文章禁止评论", "此文章禁止评论");
        }
        Comment comment = new Comment();
        BeanUtils.copyProperties(param, comment);
        String commentId = UUID.randomUUID().toString().trim().replaceAll("-", "");

//        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
//        Calendar calendar = Calendar.getInstance();
//        String dateName = df.format(calendar.getTime());
        //String commentId = String.format(NewsConstant.COMMENT_PREFIX, "");
        if (StringUtils.isEmpty(param.getCommentTargetId())) {
            return Result.error(ResponseEnum.NO_COMMENT_ID);
        }
        comment.setCommentId(commentId);
        comment.setIsDelete(0);
        comment.setIsArtificial(0);
        comment.setCreateTime(new Date());
        comment.setUpdateTime(new Date());
        comment.setUserid(user.getUserid());
        comment.setCommentType(param.getCommentType());
        comment.setTel(user.getTel());
        UserInfo userInfo = userInfoMapper.findUserInfoByUserId(user.getUserid());
        if (userInfo != null) {
            comment.setNickname(userInfo.getNickname());
        }
        if (param.getCommentType() == 2) {
            if (!StringUtils.isEmpty(param.getReplyCommentId())) {
                Comment comment1 = commentMapper.findCommentByCommentId(param.getReplyCommentId());
                if (comment1 == null) {
                    return Result.error(ResponseEnum.NOT_FOUND_COMMENT);
                }
            }
        }
        int insertNum = commentMapper.insertSelective(comment);
        if (insertNum > 0) {
            //清除redis中该文章的评论缓存信息
            String key = String.format(Constant.ARTICLE_COMMENT_KEY, comment.getCommentTargetId());
            boolean flag = redisObjectComponent.del(key);
            log.info("增加评论时，清除redis中之前的评论数据，key={}, 结果={}", key, flag);
            CommentQueryParam queryParam = new CommentQueryParam();
            queryParam.setCommentTargetId(param.getCommentTargetId());
            return this.listComment(queryParam);
        } else {
            return Result.error("发表评论或回复失败");
        }
    }

    @Override
    public Result<Integer> deleteCommentByComment(CommentParam param) {
        Comment comment = commentMapper.findCommentByCommentId(param.getCommentId());
        if (comment == null) {
            log.info("没有这个评论，commentId={}", param.getCommentId());
            return Result.error(0);
        }
        int deleteNum = commentMapper.deleteCommentByCommentId(param.getCommentId());
        if (deleteNum > 0) {
            //清除redis缓存的评论数据，该评论对应的文章下的所有评论都需要从redis中清除
            String articleId = comment.getCommentTargetId();
            String key = String.format(Constant.ARTICLE_COMMENT_KEY, articleId);
            boolean flag = redisObjectComponent.del(key);
            log.info("清除redis缓存文章评论key={}，articleId{}, 结果={}", key, articleId, flag);
        }
        return Result.success(deleteNum);
    }

    @Override
    public Result<PageInfo<Comment>> findCommentByParam(CommentFilterParam param) {
        PageHelper.startPage(param.getPage(), param.getSize());
        PageInfo<Comment> commentByParam = new PageInfo<>(commentMapper.findCommentByParam(param));
//        List<Comment> commentByParam = commentMapper.findCommentByParam(param);
        if (!CollectionUtils.isEmpty(commentByParam.getList())) {
            commentByParam.getList().forEach(comment -> {
                if (comment.getCommentType() == 2) {
                    String replyCommentId = comment.getReplyCommentId();
                    Comment commentByCommentId = commentMapper.findCommentByCommentId(replyCommentId);
                    comment.setOperation(commentByCommentId != null ? "回复:" + commentByCommentId.getNickname() : "回复");
                } else if (comment.getCommentType() == 1) {
                    comment.setOperation("评论");
                }
            });
        }


        return Result.success(commentByParam);
    }

    @Override
    public Integer loadCommentCountByArticle(String articleId) {
        return commentMapper.loadCommentCountByArticle(articleId);
    }

    @Override
    public Result listComment(CommentQueryParam param) {
        //加入缓存逻辑
        String key = String.format(Constant.ARTICLE_COMMENT_KEY, param.getCommentTargetId());
        List<Comment> commentList = (List<Comment>) redisObjectComponent.get(key);
        if (commentList == null) {
            log.info("文章articleId={}评论在缓存redis中不存在，需要从数据库中获取", param.getCommentTargetId());
            param.setCommentType(1);//评论类型
            commentList = commentMapper.listComment(param);
            for (Comment comment : commentList) {
                String userId = comment.getUserid();
                UserInfo userInfo = userInfoMapper.findUserInfoByUserId(userId);
                if (userInfo != null) {
                    comment.setUserInfo(userInfo);
                }

                String commentId = comment.getCommentId();
                String commentTargetId = comment.getCommentTargetId();

                CommentQueryParam subParam = new CommentQueryParam();
                subParam.setRootCommentId(commentId);
                subParam.setCommentTargetId(commentTargetId);
                subParam.setCommentType(2);//回复类型


                List<Comment> subCommentList = commentMapper.listComment(subParam);
                for (Comment subComment : subCommentList) {
                    String subUserId = subComment.getUserid();
                    UserInfo subUserInfo = userInfoMapper.findUserInfoByUserId(subUserId);
                    if (subUserInfo != null) {
                        subComment.setUserInfo(subUserInfo);
                    }
                    String replyCommentId = subComment.getReplyCommentId();
                    Comment replyComment = commentMapper.findCommentByCommentId(replyCommentId);
                    UserInfo replyUserInfo = userInfoMapper.findUserInfoByUserId(replyComment.getUserid());
                    subComment.setReplyUserInfo(replyUserInfo);
                    String str = banWordsService.getPureWords(subComment.getComments());
                    subComment.setComments(str);
                }
                comment.setSubCommentList(subCommentList);
                String str = banWordsService.getPureWords(comment.getComments());
                comment.setComments(str);
            }
            boolean flag = redisObjectComponent.set(key, commentList);
            log.info("文章articleId={}评论保存到缓存redis中结果={}", param.getCommentTargetId(), flag);
        } else {
            log.info("文章articleId={}评论在缓存redis中直接获取", param.getCommentTargetId());
        }

        return Result.success(commentList);
    }

    @Override
    public Result listMyComment(String userId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<Comment> myCommentList = new PageInfo<>(commentMapper.listMyComment(userId));
        if (!CollectionUtils.isEmpty(myCommentList.getList())) {
            myCommentList.getList().forEach(comment -> {
                String articleId = comment.getCommentTargetId();
                Article article = articleMapper.getArticle(articleId);
                comment.setArticle(article);
            });
        }

        return Result.success(myCommentList);
    }
}
